/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2005
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
/*
 * Created on Apr 18, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package br.ufmg.dees.insane.draw;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.geom.Ellipse2D;
import java.util.Vector;

/**
 * @author roque
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class MarkDraw extends Draw{
	private boolean labelOn;
	private String 	label;
	private byte 	labelPlace;
	private byte 	type;
	private int 	labelSize;
	private byte  	labelStyle;
	private String 	labelFont;
	private Color 	labelColor = Color.RED;
	private Color 	markColor = Color.RED;
	
	public static final byte VLINE 		= 1;
	public static final byte HLINE 		= 2;
	public static final byte PLUS		= 3;
	public static final byte TIMES 		= 4;
	public static final byte STAR 		= 5;
	public static final byte CIRC 		= 6;
	public static final byte SQUARE 	= 7;
	public static final byte TRIANGLE 	= 8;
	public static final byte DIAMOND 	= 9;
	public static final byte POINT 	    = 10;
	
	public static final byte NORTH = 1;
	public static final byte SOUTH = 2;
	public static final byte EAST = 3;
	public static final byte WEST = 4;
	
	public MarkDraw(Point loc, String lab, int size, byte place, byte type){
		this(loc, lab, size, place, type, null);
	}
	
	public MarkDraw(){
	}
	
	public MarkDraw(Point loc, String lab, int size, byte place, byte type, Object represents) {
		this.label = lab;
		this.labelPlace = place;
		this.type = type;
        this.setLocation(loc);
        this.setSize(new Dimension(size,size));
        this.setRepresents(represents);
    }
	
	public void setLabelOn(boolean l){
		this.labelOn = l;
	}
	
	public boolean isLabelOn(){
		return this.labelOn;
	}
	
	public void setLabel(String lab){
		this.label = lab;
	}
	
	public String getLabel(){
		return this.label;
	}
	
	public void setType(byte tp){
		this.type = tp;
	}
	
	public byte getType(){
		return this.type;
	}
	
	public void setLabelPlace(byte o){
		this.labelPlace = o;
	}
	
	public byte getLabelPlace(){
		return this.labelPlace;
	}
	
	public void setLabelFont(String o){
		this.labelFont = o;
	}
	
	public String getLabelFont(){
		return this.labelFont;
	}
	
	public void setLabelStyle(byte o){
		this.labelStyle = o;
	}
	
	public byte getLabelStyle(){
		return this.labelStyle;
	}
	
	public void setLabelSize(int o){
		this.labelSize = o;
	}
	
	public int getLabelSize(){
		return this.labelSize;
	}
	
	/**
     * Draws in a given Graphics.
     * @see   java.awt.Graphics
     */
    public void draw(Graphics2D g2) {
        
        int x = this.getLocation().x;
        int y = this.getLocation().y;
        int width = (int)this.getSize().width/2;
		int height = (int)this.getSize().height/2;
        
        //drawing the mark 
		switch (this.type){
		case VLINE:{
			g2.drawLine(x, y+height, x, y-height);
			break;
		}
		case HLINE:{
			g2.drawLine(x-width, y, x+width, y);
			break;
		}
		case PLUS:{
			g2.drawLine(x, y+height, x, y-height);
			g2.drawLine(x-width, y, x+width, y);
			break;
		}
		case TIMES:{
			g2.drawLine((int)(x-width*Math.cos(Math.PI/4)), (int)(y+height*Math.cos(Math.PI/4)),
						(int)(x+width*Math.cos(Math.PI/4)), (int)(y-height*Math.cos(Math.PI/4)));
			g2.drawLine((int)(x-width*Math.cos(Math.PI/4)), (int)(y-height*Math.cos(Math.PI/4)),
						(int)(x+width*Math.cos(Math.PI/4)), (int)(y+height*Math.cos(Math.PI/4)));
			break;
		}
		case STAR:{
			g2.drawLine(x, y+height, x, y-height);
			g2.drawLine(x-width, y, x+width, y);
			g2.drawLine((int)(x-width*Math.cos(Math.PI/4)), (int)(y+height*Math.cos(Math.PI/4)),
						(int)(x+width*Math.cos(Math.PI/4)), (int)(y-height*Math.cos(Math.PI/4)));
			g2.drawLine((int)(x-width*Math.cos(Math.PI/4)), (int)(y-height*Math.cos(Math.PI/4)),
						(int)(x+width*Math.cos(Math.PI/4)), (int)(y+height*Math.cos(Math.PI/4)));
			break;
		}
		case CIRC:{
			g2.drawArc(x-width,y-height,2*width,2*height,0,360);
			break;
		}
		case SQUARE:{
			g2.drawRect(x-width,y-height,2*width,2*height);
			break;
		}
		case TRIANGLE:{
			g2.drawLine(x,y-height, x+width,y+height);
			g2.drawLine(x+width,y+height, x-width,y+height);
			g2.drawLine(x-width,y+height,x,y-height);
			break;
		}
		case DIAMOND:{
			g2.drawLine(x,y-height, x+width,y);
			g2.drawLine(x+width,y, x,y+height);
			g2.drawLine(x,y+height, x-width,y);
			g2.drawLine(x-width,y,x,y-height);
			break;
		}
		case POINT:{
			
			g2.fill(new Ellipse2D.Double(x-width,y-height,2*width,2*height));
			g2.drawArc(x-width,y-height,2*width,2*height,0,360);
			break;
		}
		
		}
		
		//drawing the label
		if(this.labelOn){
			g2.setColor(labelColor);
			g2.setFont(new Font(this.labelFont, this.labelStyle, this.labelSize));
			FontMetrics metrics = g2.getFontMetrics();
			int txtWidth = metrics.stringWidth(this.label);
			int txtHeight = metrics.getHeight();
			switch (this.labelPlace){
				case 1:{
					g2.drawString(label, x-txtWidth/2, y-height);
					break;
				}
				case 2:{
					g2.drawString(label, x-txtWidth/2, y+height+txtHeight);
					break;
				}
				case 3:{
					g2.drawString(label, x+width, y);
					break;
				}
				case 4:{
					g2.drawString(label, x-width-txtWidth, y);
					break;
				}
			}
		}
		Color currentColor = markColor;
		
		Stroke currentStroke = g2.getStroke();
		
        if (isSelected()) {
        	g2.setStroke(new BasicStroke((float)0.75, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2.setColor(new Color(0, 255, 0));
            g2.draw(getBounds());
            g2.setColor(new Color(0f, 1.0f, 0f,0.3f));
            g2.fill(getBounds());
        }
        g2.setStroke(currentStroke);
        g2.setColor(currentColor);
    } 
	 /**
     * Returns the draw bounds in device units.
     *
     * @return the draw bounds
     */
    public Rectangle getBounds() {
        
        int x = this.getLocation().x;
        int y = this.getLocation().y;
        int width = this.getSize().width;
        int height = this.getSize().height;
        double scale = this.getScale();
		
        int W = (int)(4 + width * scale);
        int H = (int)(4+ height * scale); 
        return new Rectangle((int)(x - W/2), (int)(y - H/2), W, H);
    }
    
    
    public Vector<Object> getShapes() {
        return null;
    }

	/**
	 * The method return the labelColor.
	 * @return Returns The labelColor.
	 */
	public Color getLabelColor() {
		return labelColor;
	}

	/**
	 * The method set the field labelColor from the parameter labelColor.
	 * @param labelColor The labelColor to set.
	 */
	public void setLabelColor(Color labelColor) {
		this.labelColor = labelColor;
	}

	/**
	 * The method return the markColor.
	 * @return Returns The markColor.
	 */
	public Color getMarkColor() {
		return markColor;
	}

	/**
	 * The method set the field markColor from the parameter markColor.
	 * @param markColor The markColor to set.
	 */
	public void setMarkColor(Color markColor) {
		this.markColor = markColor;
	}
}

